﻿using AntdUI;
using PosClient.Controls;
using PosClient.Helper;
using PosClient.Job;
using PosClient.Model;
using PosClient.Service;
using PosClient.View.MainForm.ViewModel;
using PosClient.View.ScreenForm;
using ReactiveUI;
using Splat;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PosClient.View.MainForm
{
    public partial class MainView : Window, IViewFor<MainViewModel>
    {
        private bool isLight = true;
        object IViewFor.ViewModel
        {
            get => ViewModel;
            set => ViewModel = (MainViewModel)value;
        }
        public MainViewModel ViewModel { get; set; }

        private static ScreenView screen;

        private delegate void SetDataDelegate();

        public KeepFocusHelper KeepFocusHelper;

        static System.Timers.Timer tickTimer = new System.Timers.Timer(1000);

        public MainView()
        {
            InitializeComponent();

            InitMenu();

            InitSetting();

            InitBinding();

            InitEvent();

            setupTickTimer();
        }

        private void InitMenu()
        {
            menu_base.Items.Clear();
            foreach (var item in DataUtil.MenuList)
            {
                var rootMenu = new AntdUI.MenuItem
                {
                    Text = item.Value.Text,
                    IconSvg = item.Value.IconSvg,
                    Tag = item.Value.Tag
                };
                menu_base.Items.Add(rootMenu);
            }
        }

        private void InitSetting()
        {
            using (var conn = FreeClient.Sqlite)
            {
                JobEntity jobEntity = new JobEntity()
                {
                    JobName = "测试",
                    JobBody = "body",
                    JobStatus = 1,
                    Deleted = 0,
                    JobRound = -1,
                    JobClass = "BarcodeDownLoadJob",
                    JobCron = "0 1/5 * * * ?"
                };
                conn.Insert(jobEntity).ExecuteAffrows();
                JobEntity jobEntity1 = new JobEntity()
                {
                    JobName = "测试1",
                    JobBody = "body1",
                    JobStatus = 1,
                    Deleted = 0,
                    JobRound = -1,
                    JobClass = "BaseDataDownLoadJob",
                    JobCron = "0 1/4 * * * ?"
                };
                conn.Insert(jobEntity1).ExecuteAffrows();
                JobEntity jobEntity2 = new JobEntity()
                {
                    JobName = "测试2",
                    JobBody = "body2",
                    JobStatus = 1,
                    Deleted = 0,
                    JobRound = -1,
                    JobClass = "DiscountDownLoadJob",
                    JobCron = "0 1/3 * * * ?"
                };
                conn.Insert(jobEntity2).ExecuteAffrows();
            }

            var job = Locator.Current.GetService<JobManager>();
            job.LoadJob();
        }

        private void InitLoad()
        {
            KeepFocusHelper = new KeepFocusHelper(this, input_barcode);
            KeepFocusHelper.Start();

            screen = new ScreenView();
            screen.ShonOnMonitor();
        }

        private void InitEvent()
        {
            this.Load += MainView_Load;

            KeyDown += (s, e) =>
            {
                if (e.KeyData == Keys.Enter)
                {
                    if (!string.IsNullOrEmpty(input_barcode.Text))
                    {
                        ViewModel.GetPluCommand.Execute().Subscribe();
                    }
                    else if(ViewModel.PluList.Count > 0
                    )
                    {
                        ViewModel.ConfirmPayCommand.Execute().Subscribe();
                    }
                }
                else if (e.KeyData == Keys.Escape)
                {
                    this.Close();
                }
            };

            this.FormClosing += (s, e) =>
            {
                var dialog = MessageBox.Show("确定要退出系统？", "操作提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                e.Cancel = !(DialogResult.Yes == dialog);
                if (!e.Cancel)
                {
                    tickTimer.Stop();
                    tickTimer.Close();
                }
            };

            menu_base.SelectChanged += (s, e) =>
            {
                UserControl control = null;
                string name = e.Value.Tag.ToString();
                switch (name)
                {

                    default:
                        break;
                }
                AntdUI.Drawer.Config config = AntdUI.Drawer.config(this, control, TAlignMini.Right);
                config.Mask = true;
                AntdUI.Drawer.open(config);
            };

            button_collapse.Click += (s, e) =>
            {
                if (menu_base.Collapsed)
                {
                    menu_base.Width = (int)(150 * Config.Dpi);
                }
                else
                {
                    menu_base.Width = (int)(70 * Config.Dpi);
                }
                button_collapse.Toggle = !button_collapse.Toggle;
                menu_base.Collapsed = !menu_base.Collapsed;
            };

            this.KeyUp += (s, e) =>
            {
                pluGrid.PosGrid_KeyUp(e.KeyData);
                if (e.KeyData == Keys.Left)
                {
                    ViewModel.AddOneCommand.Execute().Subscribe();
                }
                else if (e.KeyData == Keys.Right)
                {
                    ViewModel.DelOneCommand.Execute().Subscribe();
                }
            };

            this.FormClosed += (s, e) =>
            {
                Application.Exit();
                Environment.Exit(0);
            };

            this.numberKeyboard_lite.KeyboardEvent += (s, e) =>
            {
                Console.WriteLine(s);
            };

            ViewModel.PluList.ListChanged += (s, e) =>
            {
                pluGrid.DataSource_ListChanged(s, e);
            };

            pluGrid.GridIndexEvent += (s, e) =>
            {
                if (int.Parse(s.ToString()) < ViewModel.PluList.Count)
                {
                    ViewModel.SelectPlu = ViewModel.PluList[int.Parse(s.ToString())];
                    ViewModel.Index = int.Parse(s.ToString());
                }
                else
                {
                    ViewModel.SelectPlu = new Plu(); ;
                    ViewModel.Index = -1;
                }
            };

            pluGrid.GridDataEvent += (s, e) =>
            {
                if (s.ToString() == "+")
                {
                    ViewModel.AddOneCommand.Execute().Subscribe();
                }
                else if (s.ToString() == "-")
                {
                    ViewModel.DelOneCommand.Execute().Subscribe();
                }
                ViewModel.SummaryCommand.Execute().Subscribe();
            };

            button_light.Click += (s, e) =>
            {
                isLight = !isLight;
                //这里使用了Toggle属性切换图标
                button_light.Toggle = !isLight;
                button_data.Toggle = !isLight;
                Globals.IsLight = button_light.Toggle;
                ThemeHelper.SetColorMode(this, isLight);
            };
        }

        private void InitBinding()
        {
            ViewModel = Locator.Current.GetService<MainViewModel>();
            this.WhenActivated(d =>
            {
                this.Bind(ViewModel,
                    vm => vm.PluList,
                    v => v.pluGrid.DataSource
                    ).DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.TotalCount,
                    v => v.label_totalcount.Text
                    ).DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.TotalAmount,
                    v => v.label_totalamount.Text
                    ).DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.Barcode,
                    v => v.input_barcode.Text
                    ).DisposeWith(d);

                #region Vip

                this.OneWayBind(ViewModel,
                    vm => vm.VipBase,
                    v => v.label_vipcode.Text,
                    ConvertVipCode
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.VipBase.VipLevel.LevelName,
                    v => v.label_viptype.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.VipBase.GrowthCurrent,
                    v => v.label_growth.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.VipBase.PointCurrent,
                    v => v.label_bonus.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.VipBase.TicketCount,
                    v => v.label_ticket.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.VipBase.DepositCurrent,
                    v => v.label_deposit.Text
                    ).DisposeWith(d);

                #endregion

                #region BtnCommand

                this.BindCommand(ViewModel, vm => vm.RemoveCommand, v => v.btnRemove).DisposeWith(d);
                this.BindCommand(ViewModel, vm => vm.SearchVipCommand, v => v.btnSearchMember).DisposeWith(d);
                this.BindCommand(ViewModel, vm => vm.GetPluCommand, v => v.btnSeach).DisposeWith(d);
                this.BindCommand(ViewModel, vm => vm.ClearCartCommand, v => v.btnClearCart).DisposeWith(d);

                #endregion

                #region WhenAnyValue

                ViewModel.WhenAnyValue(vm => vm.VipBase.Lables).Do(x =>
                {
                    if (x != null && x.Count > 0)
                    {
                        flowPanel_lables.Controls.Clear();
                        foreach (var lable in x)
                        {
                            AntdUI.Tag tag = new AntdUI.Tag();
                            tag.CloseIcon = false;
                            tag.Text = lable;
                            tag.AutoSize = true;
                            tag.Type = TTypeMini.Primary;
                            flowPanel_lables.Controls.Add(tag);
                        }
                    }
                }).Subscribe().DisposeWith(d);

                this.ViewModel.WhenAnyValue(vm => vm.Index).Subscribe(x =>
                {
                    if (x > -1)
                    {
                        pluGrid.Index = x;
                    }
                }).DisposeWith(d);

                #endregion

                #region Subscribe

                ViewModel.GetPluCommand.Subscribe(result =>
                {
                    if (!result.Success)
                    {
                        var config1 = new AntdUI.Tooltip.Config(input_barcode, $"查询失败{result.Message}");
                        config1.ArrowAlign = AntdUI.TAlign.Top;
                        AntdUI.Tooltip.open(config1);
                    }
                    else
                    {
                        input_barcode.Clear();
                    }    
                    input_barcode.SelectAll();
                }).DisposeWith(d);

                #endregion

            });
        }


        private string ConvertVipCode(VipBase arg)
        {
            return arg.VipCode + "\r\n" + arg.VipName;
        }

        private void MainView_Load(object sender, EventArgs e)
        {
            InitLoad();
        }


        private void RefreshTime()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new SetDataDelegate(RefreshTime));
            }
            else
            {
                label_SystemDate.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            }
        }

        private void setupTickTimer()
        {
            tickTimer.AutoReset = true; //设置是执行一次（false）还是一直执行(true)
            tickTimer.Elapsed += (o, a) =>
            {
                RefreshTime();
            };
            tickTimer.Enabled = true;
        }

    }
}
